package com.ffcs.crmd.tsp.server.jdbc.service.impl;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.ffcs.crmd.tsp.common.exception.TspException;
import com.ffcs.crmd.tsp.server.jdbc.entity.Job;
import com.ffcs.crmd.tsp.server.jdbc.entity.JobDetail;
import com.ffcs.crmd.tsp.server.jdbc.entity.JobIdentityInfo;
import com.ffcs.crmd.tsp.server.jdbc.entity.SliceGroup;
import com.ffcs.crmd.tsp.server.jdbc.repository.JobRepository;
import com.ffcs.crmd.tsp.server.jdbc.service.IJobDetailService;
import com.ffcs.crmd.tsp.server.jdbc.service.IJobIdentityInfoService;
import com.ffcs.crmd.tsp.server.jdbc.service.IJobService;
import com.ffcs.crmd.tsp.server.jdbc.service.ISliceGroupService;

/**
 * 
 * 功能说明:任务服务
 *
 * @author ZHONGFUHUA
 * 
 * @since 1.0.0-SNAPSHOT
 *
 */
public class JobServiceImpl implements IJobService {
    
    private IJobIdentityInfoService jobIdentityInfoService;
    
    private IJobDetailService       jobDetailService;
    
    private ISliceGroupService      sliceGroupService;
    
    private JobRepository           jobRepository = new JobRepository();
    
    public JobServiceImpl() {
    }
    
    @Override
    public Job get(Connection conn, Job job) throws TspException {
        List<Object> params = new ArrayList<Object>();
        params.add(job.getClusterName());
        params.add(job.getName());
        params.add(job.getId());
        return jobRepository.query(GET_JOB, params, conn);
    }
    
    @Override
    public int querySize(Connection conn, Job job) throws TspException {
        List<Object> params = new ArrayList<Object>();
        String sql = rtp(SELECT_JOB, job, params, true);
        return jobRepository.queryRows(sql, params, conn);
    }
    
    @Override
    public List<Job> query(Connection conn, Job job) throws TspException {
        List<Object> params = new ArrayList<Object>();
        String sql = rtp(SELECT_JOB, job, params, false);
        return jobRepository.queryList(sql, params, conn);
    }
    
    @Override
    public List<Job> queryPage(Connection conn, Job job) throws TspException {
        List<Object> params = new ArrayList<Object>();
        String sql = rtpPage(SELECT_JOB, job, params);
        return jobRepository.queryList(sql, params, conn);
    }
    
    @Override
    public boolean add(Connection conn, Job job) throws TspException {
        List<Object> params = new ArrayList<Object>();
        params.add(TspSeqServiceImpl.getSeq());
        params.add(job.getName());
        params.add(job.getJobClass());
        params.add(job.getCronExpression());
        params.add(job.getRepeatCount());
        params.add(job.getRepeatInterval());
        params.add(job.getExecuteTimeout());
        params.add(job.getBufferSizeLimit());
        params.add(job.getType());
        params.add(job.getRepeatType());
        params.add(job.getMisfireInstruction());
        params.add(1);
        params.add(job.getJobGroupId());
        params.add(job.getResetDeathDelayTime());
        params.add(job.getTimeoutPolicy());
        params.add(job.getPriority());
        params.add(job.getClusterName());
        params.add(job.getDescription());
        return jobRepository.execute(INSERT_JOB, params, conn);
    }
    
    @Override
    public boolean update(Connection conn, Job job) throws TspException {
        List<Object> params = new ArrayList<Object>();
        params.add(job.getJobClass());
        params.add(job.getCronExpression());
        params.add(job.getRepeatCount());
        params.add(job.getRepeatInterval());
        params.add(job.getExecuteTimeout());
        params.add(job.getBufferSizeLimit());
        params.add(job.getType());
        params.add(job.getRepeatType());
        params.add(job.getMisfireInstruction());
        params.add(job.getJobGroupId());
        params.add(job.getResetDeathDelayTime());
        params.add(job.getTimeoutPolicy());
        params.add(job.getPriority());
        params.add(job.getDescription());
        params.add(job.getId());
        return jobRepository.execute(UPDATE_JOB, params, conn);
    }
    
    @Override
    public boolean delete(Connection conn, Job job) throws TspException {
        List<Object> params = new ArrayList<Object>();
        String sql = rtpDelete(DELETE_JOB, job, params);
        
        List<Job> jobList = new ArrayList<Job>();
        Job qjob = this.get(conn, job);
        if(qjob != null){
            jobList.add(qjob);
        }else{
            jobList.addAll(this.query(conn, job));
        }
        
        for (Job rjob : jobList) {
            JobIdentityInfo jobIdentityInfo = new JobIdentityInfo();
            jobIdentityInfo.setJobId(rjob.getId());
            jobIdentityInfoService.delete(conn, jobIdentityInfo);
            
            JobDetail jobDetail = new JobDetail();
            jobDetail.setJobId(rjob.getId());
            jobDetailService.delete(conn, jobDetail);
            
            SliceGroup sliceGroup = new SliceGroup();
            sliceGroup.setJobId(rjob.getId());
            sliceGroupService.delete(conn, sliceGroup);
        }
        return jobRepository.execute(sql, params, conn);
    }
    
    /**
     * 
     * 功能说明:
     * 
     * @param sql
     * @param jobIdentityInfo
     * @param params
     * @return
     * @throws TspException 
     */
    private String rtpDelete(String sql, Job job, final List<Object> params) throws TspException {
        if (job.getId() == null && job.getJobGroupId() == null) {
            throw new TspException("delete job ['id' or 'jobGroupId'] can't be null at the same time！");
        }
        
        if (job.getId() != null) {
            sql += " AND " + COL_ID + " = ?";
            params.add(job.getId());
        }
        
        if (job.getJobGroupId() != null) {
            sql += " AND " + COL_JOB_JOB_GROUP_ID+ " = ?";
            params.add(job.getJobGroupId());
        }
        
        return sql;
    }
    
    
    /**
     * 
     * 功能说明:
     * 
     * @param sql
     * @param job
     * @param params
     * @return
     */
    private String rtp(String sql, Job job, final List<Object> params, boolean isLike) {
        if (job.getJobGroupId() != null) {
            sql += " AND TJ." + COL_JOB_JOB_GROUP_ID + " = ?";
            params.add(job.getJobGroupId());
        }
        
        if (StringUtils.isNoneBlank(job.getName())) {
            if (isLike) {
                sql += " AND TJ." + COL_NAME + " LIKE ?";
                params.add("%" + job.getName() + "%");
            }else{
                sql += " AND TJ." + COL_NAME + " = ?";
                params.add(job.getName());
            }
        }
        
        if (StringUtils.isNoneBlank(job.getClusterName())) {
            sql += " AND TJ." + COL_CLUSTER_NAME + " = ?";
            params.add(job.getClusterName());
        }
        
        
        if(StringUtils.isNoneBlank(job.getDescription())){
            sql += " AND TJ." + COL_DESCRIPTION + " LIKE ?";
            params.add("%" + job.getDescription() + "%");
        }
        
        if (StringUtils.isNoneBlank(job.getIdentity())) {
            if(isLike){
                sql += " AND TJII." + COL_JOB_IDENTITY_INFO_IDENTITY + " LIKE ?";
                params.add("%" + job.getIdentity() + "%");
            }else{
                sql += " AND TJII." + COL_JOB_IDENTITY_INFO_IDENTITY + " = ?";
                params.add(job.getIdentity());
            }
        }
        return sql;
    }
    
    /**
     * 
     * 功能说明:
     * 
     * @param sql
     * @param job
     * @param params
     * @return
     */
    private String rtpPage(String sql, Job job, final List<Object> params) {
        String rsql = rtp(sql, job, params, true);
        rsql += " LIMIT ?,?";
        params.add(job.getPageNumber());
        params.add(job.getPageSize());
        return rsql;
    }
    
    /**
     * 功能说明: 设置jobIdentityInfoService
     *
     * @param jobIdentityInfoService jobIdentityInfoService 
     */
    @Override
    public void setJobIdentityInfoService(IJobIdentityInfoService jobIdentityInfoService) {
        this.jobIdentityInfoService = jobIdentityInfoService;
    }
    
    /**
     * 功能说明: 设置jobDetailService
     *
     * @param jobDetailService jobDetailService 
     */
    @Override
    public void setJobDetailService(IJobDetailService jobDetailService) {
        this.jobDetailService = jobDetailService;
    }
    
    /**
     * 功能说明: 设置sliceGroupService
     *
     * @param sliceGroupService sliceGroupService 
     */
    @Override
    public void setSliceGroupService(ISliceGroupService sliceGroupService) {
        this.sliceGroupService = sliceGroupService;
    }
    
}
